package com.lwl.concurrency.collection;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 原子变量测试
 * Created by liwenlong on 2018/1/17 11:34
 */
public class CasTest {
    static class Account {
        private AtomicLong balance;//储存账号的余额

        public Account() {
            this.balance = new AtomicLong();
        }

        /**
         * 返回余额属性值
         **/
        public long getBalance() {
            return balance.get();
        }

        /**
         * 用来设置余额属性值
         **/
        public void setBalance(long balance) {
            this.balance.set(balance);
        }

        //来增加余额属性值。
        public void addAmount(long amount) {
            this.balance.getAndAdd(amount);
        }

        //来减少余额属性值。
        public void subtractAmount(long amount) {
            this.balance.getAndAdd(-amount);
        }
    }

    static class Company implements Runnable {

        private Account account;

        public Company(Account account) {
            this.account = account;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                account.addAmount(1000);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class Bank implements Runnable {

        private Account account;

        public Bank(Account account) {
            this.account = account;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                account.subtractAmount(1000);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Account account = new Account();
        account.setBalance(1000);
        Company company = new Company(account);
        Bank bank = new Bank(account);
        Thread companyThread = new Thread(company);
        Thread bankThread = new Thread(bank);
        System.out.printf("Account : Initial Balance: %d\n", account.getBalance());
        companyThread.start();
        bankThread.start();
        try {
            companyThread.join();
            bankThread.join();
            System.out.printf("Account : Final Balance: %d\n", account.getBalance());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
}
